
import dayjs from "dayjs"
import { Md5 } from 'ts-md5';

import store from '@/store';
import { useMainStore } from '@/store/modules/store';
import serviceTools from '@/common/service';
import useService from "@/hooks/useService";
import useBillId from "@/hooks/useBillId";
import { initRdsDict, getRdsSysConfig } from '@/hooks/init';

import type { LowcodeMenuBtnsHookProxy, LowcodeMenuBtnDelProxy, LowcodeMenuBtnCancelProxy, LowcodeMenuBtnAuditProxy, LowcodeBillDisabledProxy, LowcodeMenuBtnSaveProxy, LowcodeSaveListProxy } from "./interface";
import { EBillApproveStatus, EBillStatus, ECBillApproveStatus, ECBillStatus, lowcodeDefaultField, LOWCODERUNTIMEUNIQUEKEY } from "../constant";
import type { LowcodeField, LowcodeSaveModel } from '../interface';

const useLowcodeMenuBtns = (hookProxy?: LowcodeMenuBtnsHookProxy) => {
  const mainService = useService({ prefix: "mainApi" });
  const mainStore = useMainStore();
  const { createBillId } = useBillId({})

  const getFieldVal = (fieldConf: LowcodeField) => {
    const { modifyUserField, modifyDtField, mkUserField, mkDtField } = fieldConf;
    const UserNo = store?.state?.value?.main?.loginInfo?.sUser;
    const dateTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    return {
      newField: { [modifyUserField]: UserNo, [modifyDtField]: dateTime, [mkUserField]: UserNo, [mkDtField]: dateTime },
      modifiedField: { [modifyUserField]: UserNo, [modifyDtField]: dateTime },
    };
  };

  const handleDeleteBill = async (proxy: LowcodeMenuBtnDelProxy) => {
    const { BillId, UserNo, ModuleCode } = proxy || {};
    uni.showLoading({ title: "处理中...", mask: true});
    const fetchReq = [{ BillId, UserNo }], fetchReqProxy = { ModuleCode };
    const fetchRes = await mainService.request<{}, any>(LOWCODERUNTIMEUNIQUEKEY, "EnjoyBillsDelete", fetchReq, "", "", fetchReqProxy);
    uni.hideLoading();
    if ((!fetchRes || !Array.isArray(fetchRes) || !fetchRes?.length || fetchRes?.[0]?.Flag === "0")) {
      const errMsg = fetchRes?.[0]?.Msg;
      errMsg && serviceTools.enjoyShowToast(errMsg, 3500, "error");
      return false;
    }
    serviceTools.enjoyShowToast("删除成功！");
    return true;
  };
  
  const handleCancelBill = async (proxy: LowcodeMenuBtnCancelProxy) => {
    const { BillId, UserNo, ModuleCode } = proxy || {};
    uni.showLoading({ title: "处理中...", mask: true});
    const fetchReq = [{ BillId, UserNo }], fetchReqProxy = { ModuleCode };
    const fetchRes = await mainService.request<{}, any>(LOWCODERUNTIMEUNIQUEKEY, "EnjoyBillsCancel", fetchReq, "", "", fetchReqProxy);
    uni.hideLoading();
    
    if ((!fetchRes || !fetchRes?.PrcessInFos || !Array.isArray(fetchRes?.PrcessInFos) || !fetchRes?.PrcessInFos?.length || fetchRes?.PrcessInFos?.[0]?.Flag === "0")) {
      const errMsg = fetchRes?.PrcessInFos?.[0]?.ErrInFo;
      errMsg && serviceTools.enjoyShowToast(errMsg, 3500, "error");
      return false;
    }

    serviceTools.enjoyShowToast("作废成功！");
    return true;
  };

  const handleAuditValidate = async (proxy: { InputAuditUserNo: string; MdCode: string; WkPassword: string }) => {
    const p = { ...proxy, WkPassword: new Md5().appendStr(`${proxy?.WkPassword?.toLowerCase()}${proxy?.InputAuditUserNo}`).end() };
	  const validateAuditRes = await mainService.request<any, string>("ValidateAuditLimit", "", p);
    return validateAuditRes;
  };

  const handleAuditBill = async (proxy: LowcodeMenuBtnAuditProxy) => {
    const { BillId, UserNo, ModuleCode } = proxy || {};

    if (!BillId) {
      serviceTools.enjoyShowToast("请先保存单据，再审核！");
      return false;
    }

    uni.showLoading({ title: "正在审核单据，请稍等...", mask: true});
    const fetchReq = { BillId: BillId, UserNo }, fetchReqProxy = { ModuleCode };
    const auditRes = await mainService.request<{}, any>(LOWCODERUNTIMEUNIQUEKEY, "EnjoyBillAudit", fetchReq, "", "", fetchReqProxy);
    uni.hideLoading();

    return !auditRes;
  };

  const createSaveModel = (proxy?: LowcodeMenuBtnSaveProxy) => {
    const { BillId = "", mainData, tableData, mainTable, detailListTable, fieldConf = lowcodeDefaultField } = proxy || {};
    const { idField = "c_id" } = fieldConf;
    const { newField, modifiedField } = getFieldVal(fieldConf);
    const loginInfo = mainStore?.loginInfo;
    const tenantId = loginInfo && loginInfo.sTenantId ? loginInfo.sTenantId : '';
    
    // 注意字段的数据类型，比如，数字类型的用字符串就存不上

    const saveModel: LowcodeSaveModel = {
      NewList: BillId ? [] : [{ ...mainData, ...newField }],
      ModifiedList: BillId ? [{ ...mainData, ...modifiedField }] : [],
      DelList: [],
      TableName: mainTable?.tableName,
      PrimaryKeys: mainTable?.primaryKeys,
      ChildData: [],
      BillSet: {
        BillIdKeyValue: { key: idField, value: BillId },
        BillVariable: tenantId ? (tenantId + "-") : "",
        TableName: mainTable?.tableName,
        // BillName: ""
      }
    };

    detailListTable?.forEach((item, index) => {
			const tbIdxData = tableData?.[index];
			if (tbIdxData) {
				saveModel.ChildData?.push({
					RelationName: item.tableName,
					ParentTableName: mainTable?.tableName,
					ChildTableName: item.tableName,
					ParentColumnNames: [idField],
					ChildColumnNames: [idField],
					ChildSaveModel: {
						TableName: item.tableName,
						PrimaryKeys: item.primaryKeys,
						NewList: tbIdxData?.NewList || [],
						ModifiedList: tbIdxData?.ModifiedList || [],
						DelList: tbIdxData?.DelList || []
					}
				})
			}
		});
    return saveModel;
  };

  const handleSaveBill = async (proxy?: LowcodeMenuBtnSaveProxy) => {
    const { BillId, uniqueKey = LOWCODERUNTIMEUNIQUEKEY, mainData, ModuleCode } = proxy || {};
    const saveModel = createSaveModel(proxy);
    if (!saveModel) {
      serviceTools.enjoyShowToast("保存参数信息不能为空！");
      return false;
    }

    if (!BillId && !saveModel.BillSet) {
      serviceTools.enjoyShowToast("单号规则[BillSet]不能为空！");
      return false;
    }

    const idRet = !BillId ? await createBillId(saveModel?.BillSet, mainData, uniqueKey) : undefined;
    if (idRet && idRet?.message) {
      serviceTools.enjoyShowToast(idRet.message);
      return false
    }

    uni.showLoading({ title: "正在保存,请稍等.....", mask: true });
    const fetchReqProxy = { ModuleCode };
    const fetchRes = await mainService.request<{}, any>(LOWCODERUNTIMEUNIQUEKEY, "EnjoyBillSaveNew", saveModel, "", "", fetchReqProxy);
    uni.hideLoading();

    if (!fetchRes) {
      return false;
    }

    if (fetchRes?.IsNewBillConflict) {
      serviceTools.enjoyShowToast("生成单号冲突，请重试！");
      return false;
    }
    serviceTools.enjoyShowToast("数据保存成功！");
    return fetchRes?.BillId || true;
  };

  const billDisabled = (proxy?: LowcodeBillDisabledProxy) => {
    const { mdLimit, approving, isSystemDictDisable, field = { approveStatusField: "c_approve_status", statusField: "c_status" }, editableStatus, disableStatus = [], mainData } = proxy || {};
    let newdisabled = (mdLimit || "").indexOf("W") < 0;

    const billStatus = () => ({
      appStatus: mainData?.[`${field?.approveStatusField}`] || (isSystemDictDisable ? ECBillApproveStatus.NotYetApproved : EBillApproveStatus.NotYetApproved), //'尚未审批',
      status: mainData?.[`${field?.statusField}`] || (isSystemDictDisable ? ECBillStatus.NotApproved : EBillStatus.NotApproved), // '尚未审核',
      printStatus: "",
      editableStatus: editableStatus || []
    });

    if (!newdisabled) {
      const {
        status = isSystemDictDisable ? ECBillStatus.NotApproved : EBillStatus.NotApproved,
        appStatus = isSystemDictDisable ? ECBillApproveStatus.NotYetApproved : EBillApproveStatus.NotYetApproved,
        editableStatus
      } = billStatus?.() || {};

      newdisabled = (appStatus !== EBillApproveStatus.NotYetApproved && appStatus !== ECBillApproveStatus.NotYetApproved && appStatus !== EBillApproveStatus.ApprovalFailed && appStatus !== ECBillApproveStatus.ApprovalFailed);

      if (!newdisabled) {
        const editable = [...(editableStatus || []), EBillStatus.NotApproved, ECBillStatus.NotApproved].includes(status) === false;
        newdisabled = disableStatus.length > 0 ? [...disableStatus, ECBillStatus.Reviewed, EBillStatus.Reviewed, ECBillStatus.Voided, EBillStatus.Voided].includes(status) : editable;
      }
    }

    if (!newdisabled && approving) {
      newdisabled = true;   // TODO 可修改字段
    }

    return newdisabled;
  };


	const createSaveListModel = (tableModel : LowcodeSaveListProxy) => {
		const { fieldConf = lowcodeDefaultField } = tableModel || {};
		const { newField, modifiedField } = getFieldVal(fieldConf);

		const saveModel = {
			NewList: tableModel.NewList?.map(m => ({ ...m, ...newField })),
			ModifiedList: tableModel.ModifiedList.map(m => ({ ...m, ...modifiedField })),
			DelList: tableModel.DelList,
			TableName: tableModel?.tableName || '',
			PrimaryKeys: tableModel?.primaryKeys || [],
		}

		return saveModel
	}

	const handleSaveList = async (proxy ?: LowcodeSaveListProxy) => {
		const { ModuleCode } = proxy || {};
		const saveModel = createSaveListModel(proxy);
		if (!saveModel) {
			serviceTools.enjoyShowToast("保存参数信息不能为空！");
			return false;
		}

		uni.showLoading({ title: "正在保存,请稍等.....", mask: true });
		const fetchReqProxy = { ModuleCode };
		const fetchRes = await mainService.request<{}, any>(LOWCODERUNTIMEUNIQUEKEY, "EnjoyListSave", saveModel, "", "", fetchReqProxy);
		uni.hideLoading();

		if (fetchRes?.HasException) {
			return false;
		}

		serviceTools.enjoyShowToast("数据保存成功！");
		return true;
	}

	return { handleDeleteBill, handleCancelBill, handleAuditBill, handleAuditValidate, billDisabled, handleSaveBill, handleSaveList };
}

export default useLowcodeMenuBtns;